package com.arcticcoding.nxtphone;

import java.io.IOException;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.arcticcoding.telemetrie.TelemetrieServer;
import com.arcticcoding.telemetrie.TelemetrieServer.TelemetrieServerBinder;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Server;

public class MainActivity extends Activity {
	
	private static final String TAG 			= "com.arcticcoding.nxtphone.MainActivity";
	private static final String MARVIN_ADDRESS 	= "00:16:53:15:9E:DB";
	
	private 				TelemetrieServer 			server;
	private static final 	int 						TCP_PORT = 2045;
	private static final 	int 						UDP_PORT = 2046;
	protected static		Server 						networkServer;
	private 				RedirectListener          	redirect;
	
	private WifiManager wifiManager;
	private WifiInfo wifiInfo;
	
	private ServiceConnection serverConn = new ServiceConnection() {
		
		@Override
		public void onServiceDisconnected(ComponentName name) {
			Log.d(TAG, "ServerService disconnected");			
		}
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			TelemetrieServerBinder binder = (TelemetrieServerBinder) service;	
			server = binder.getService();
			try {
				server.bindServer(TCP_PORT, UDP_PORT);
				runOnUiThread(new Runnable() {
					@Override
					public void run() {
						Toast.makeText(getApplicationContext(), "TelemetrieServer bound", Toast.LENGTH_SHORT).show();
					}
				});
			} catch(IOException e) {
				runOnUiThread(new Runnable() {
					@Override
					public void run() {
						Toast.makeText(getApplicationContext(), "Can't bind TelemetrieServer! Please restart.", Toast.LENGTH_LONG).show();
					}
				});
				e.printStackTrace();
			}
			Log.d(TAG, "ServerService connected and bound");
		}
	};

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		Intent serverIntent = new Intent(this, TelemetrieServer.class);
		bindService(serverIntent, serverConn, Context.BIND_AUTO_CREATE);
		
		wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
		wifiInfo = wifiManager.getConnectionInfo();
		
		TextView networkField = (TextView) findViewById(R.id.networkField);
		String network = getNetwork();
		if (network != null && network.trim().length() != 0)
			networkField.setText(" " + network);
		
		TextView ipAddresssField = (TextView) findViewById(R.id.ipAddressField);
		String ip = getIPAddress();
		if (!ip.matches("0.0.0.0"))
			ipAddresssField.setText(" " + ip);
	}
	
	public void onStart() {
		Intent serverIntent = new Intent(this, TelemetrieServer.class);
		bindService(serverIntent, serverConn, Context.BIND_AUTO_CREATE);
		super.onStart();
	}

	@Override
	public void onStop() {
		unbindService(serverConn);
		super.onStop();
	}
	
	/**
	 * 
	 * @throws IOException
	 */
	private void startServer() throws IOException {
        networkServer = new Server() {
                protected Connection newConnection() {
                        return new MovementConnection();
                }
        };       
        
        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(MARVIN_ADDRESS);
        
        redirect = new RedirectListener(device);
                
        Network.register(networkServer);
        networkServer.addListener(redirect);
        networkServer.bind(Network.port);
        networkServer.start();
        
        Log.d(TAG, "Server started !");
	}
	
	/**
	 * 
	 * @author steffenschuhmann
	 *
	 */
	static class MovementConnection extends Connection {
        public String name;
	}
	
	/**
	 * 
	 * @param view The event View
	 */
	public void clickButton(View view) {
		switch(view.getId()) {
		case R.id.btnConnectToMarvin:
				try {
					startServer();
					Toast.makeText(this, "Redirector started", Toast.LENGTH_SHORT).show();
				} catch(IOException e) {
					Toast.makeText(this, "Can't start redirect", Toast.LENGTH_SHORT).show();
					e.printStackTrace();
					//TODO Shutdown server here
				}
			break;
		default:
			Log.wtf(TAG, "Unknown view");
		}
	}
	
	/**
	 * Liefert die IP-Adresse des Geraets zurueck
	 * 
	 * @return	IP-Adresse als String
	 */
	private String getIPAddress() {
		int myIp = wifiInfo.getIpAddress();
		
		return (myIp   			& 0xFF) + "." +
        	((myIp >> 8 ) 		& 0xFF) + "." +
        	((myIp >>  16 ) 	& 0xFF) + "." +
        	((myIp >> 24)       & 0xFF);
    }
	
	/**
	 * Liefert den Namen des Netzwerks zurueck
	 * 
	 * @return	Name des Netzwerks
	 */
	private String getNetwork() {
		return wifiInfo.getSSID();
	}


}
